package com.atguigu.tingshu.order.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.MD5;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.order.LocalMsg;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.adapder.PayWays;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.LocalMsgMapper;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.TrackListVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;

import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Qualifier("com.atguigu.tingshu.user.client.UserInfoFeignClient")
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Qualifier("com.atguigu.tingshu.album.client.AlbumInfoFeignClient")
    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderDerateMapper orderDerateMapper;
    @Autowired
    private LocalMsgMapper localMsgMapper;
    @Autowired
    private List<PayWays> payWays;


    @Override
    public OrderInfoVo trade(TradeVo tradeVo) {
        Long userId = AuthContextHolder.getUserId();
        // 付款项是专辑、声音、vip套餐（某一种）
        // 获取付款项类型（1001：专辑 1002：声音 1003：vip套餐）
        String itemType = tradeVo.getItemType();
        OrderInfoVo orderInfoVo = null;
        orderInfoVo = switch (itemType) {
            case "1001" -> dealAlbumTypeItem(tradeVo, userId);
            case "1002" -> dealTrackTypeItem(tradeVo, userId);
            case "1003" -> dealVipTypeItem(tradeVo, userId);
            default -> null;
        };
        String sign = SignHelper.getSign(JSONObject.parseObject(JSONObject.toJSONString(orderInfoVo), Map.class));
        orderInfoVo.setSign(sign);// 订单信息的签名（未来在提交订单，判断提交订单的幂等性）判断多次提交的订单是否是同一笔订单(订单数据是否被修改)

        //防止订单重复提交
        List<Long> collect = orderInfoVo.getOrderDetailVoList().stream().map(OrderDetailVo::getItemId).toList();
        String encrypt = MD5.encrypt(collect.toString());
        String multiportRepeatKey = AuthContextHolder.getUserId() + ":" + encrypt;
        redisTemplate.opsForValue().set(multiportRepeatKey,"resubmission",1, TimeUnit.DAYS);
        return orderInfoVo;
    }

    @Override
    public Map<String, Object> submitOrder(OrderInfoVo orderInfoVo) {
        Long userId = AuthContextHolder.getUserId();
        //校验请求是否合法
        String tradeNo = orderInfoVo.getTradeNo();
        if (!StringUtils.hasText(tradeNo)){
            throw new GuiguException(201, "非法请求");
        }
        //2.签名校验订单数据是否被修改
        String jsonString = JSONObject.toJSONString(orderInfoVo);
        Map orderMap = JSONObject.parseObject(jsonString, Map.class);
        orderMap.put("payWay","");
        SignHelper.checkSign(orderMap);

        //防止订单重复提交（订单数据的幂等性）：接口幂等性：对同一接口发送的请求，不管是多少次，得到的结果应该都是一样的
        List<Long> collect = orderInfoVo.getOrderDetailVoList().stream().map(OrderDetailVo::getItemId).toList();
        String encrypt = MD5.encrypt(collect.toString());
        String checkMultiPortKey = userId +":" + encrypt;
        String script = """
                if redis.call("exists",KEYS[1])
                then
                    return redis.call("del",KEYS[1])
                else
                    return 0
                end""";
        Long execute = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(checkMultiPortKey));
        if (execute == 0){
            throw new GuiguException(201,"订单重复提交");
        }
        // 生成订单编号
        String orderNo = RandomStringUtils.random(15, true, false);
        //判断支付方式(根据不同的支付方式选择不同的支付逻辑)
        String payWay = orderInfoVo.getPayWay();
        for (PayWays way : payWays) {
            if (way.supportPayWay(payWay)){
                way.payWay(orderInfoVo,orderNo,userId);
            }
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("orderNo", orderNo);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrderInfo(OrderInfoVo orderInfoVo, String orderNo, Long userId) {

        try {
            // 1.保存订单基本信息
            OrderInfo orderInfo = saveOrderBasicInfo(orderNo, orderInfoVo, userId);

            // 2.保存订单减免信息
            saveOrderDerateInfo(orderInfoVo, orderInfo.getId());

            // 3.保存订单详情信息
            saveOrderDetailInfo(orderInfoVo, orderInfo.getId());

            // 4.初始化本地消息表
            saveLocalMsg(orderNo);

        } catch (Exception e) {
            throw new GuiguException(201, "服务内部出现问题");
        }
    }

    @Override
    public void paySuccess(String orderNo) {
        // 根据订单编号查询订单信息
        OrderInfo orderInfo = getOrderInfoAndDetail(orderNo);
        if (orderInfo == null) {
            throw new GuiguException(201, "订单不存在");
        }
        //修改订单的状态
        int count = orderInfoMapper.updateOrderStatus(orderNo);
        if (count == 0) {
            log.error("订单状态未修改成功");
        } else {
            log.info("订单状态修改成功");
        }
        String orderInfoStr = JSONObject.toJSONString(orderInfo);
        // 记录订单支付流水（3种情况）
        UserPaidRecordVo userPaidRecordVo = prepareUserPaidRecordMsgVo(orderInfo);
        rabbitService.sendMessage(MqConst.EXCHANGE_USER, MqConst.ROUTING_USER_PAY_RECORD, JSONObject.toJSONString(userPaidRecordVo));
        //修改ES中专辑购买量
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_ES_STAT_UPDATE, orderInfoStr);
        //修改数据库中专辑购买量
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_STAT_UPDATE, orderInfoStr);
    }

    /**
     * 准备用户支付流水信息
     * @param orderInfo 订单信息
     * @return UserPaidRecordVo
     */
    private UserPaidRecordVo prepareUserPaidRecordMsgVo(OrderInfo orderInfo) {
        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        userPaidRecordVo.setOrderNo(orderInfo.getOrderNo());
        userPaidRecordVo.setUserId(orderInfo.getUserId());
        userPaidRecordVo.setItemType(orderInfo.getItemType());
        List<Long> collect = orderInfo.getOrderDetailList().stream().map(OrderDetail::getItemId).toList();
        userPaidRecordVo.setItemIdList(Lists.newArrayList(collect));
        return userPaidRecordVo;
    }

    /**
     * 根据订单编号查询订单信息
     * @param orderNo 订单编号
     * @return OrderInfo
     */
    private OrderInfo getOrderInfoAndDetail(String orderNo) {
        // 1.查询订单的基本数据
        OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        if (orderInfo == null){
            throw new GuiguException(201, "订单信息不存在");
        }
        Long orderId = orderInfo.getId();
        // 2.查询订单详情数据
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderId));
        // 3.查询订单减免数据
        List<OrderDerate> orderDerates = orderDerateMapper.selectList(new LambdaQueryWrapper<OrderDerate>().eq(OrderDerate::getOrderId, orderDetails));
        // 4.查询订单状态名字(0901 0902 0903)
        String orderStatus = orderInfo.getOrderStatus();
        String orderStatusName = getOrderStatusName(orderStatus);
        // 5.查询订单支付方式的名字(1101 1102 1103)
        String payWay = orderInfo.getPayWay();
        String payWayName = getPayWayName(payWay);
        // 6.封装
        orderInfo.setOrderStatusName(orderStatusName);
        orderInfo.setPayWayName(payWayName);
        orderInfo.setOrderDetailList(orderDetails);
        orderInfo.setOrderDerateList(orderDerates);
        // 7.返回结果
        return orderInfo;
    }

    /**
     * 根据支付类型查询支付类型名字
     * @param payWay 支付类型
     * @return 支付类型名字
     */
    private String getPayWayName(String payWay) {

        return switch (payWay) {
            case "1101" -> "微信支付";
            case "1102" -> "支付宝支付";
            case "1103" -> "余额支付";
            default -> "";
        };
    }

    /**
     * 根据订单状态查询订单状态名字
     * @param orderStatus 订单状态
     * @return 订单状态名字
     */
    private String getOrderStatusName(String orderStatus) {

        return switch (orderStatus) {
            case "0901" -> "未支付";
            case "0902" -> "已支付";
            case "0903" -> "已关闭";
            default -> "";
        };
    }

    /**
     * 保存本地消息表
     * @param orderNo 订单编号
     */
    private void saveLocalMsg(String orderNo) {
        LocalMsg localMsg = new LocalMsg();
        localMsg.setStatus(0);
        localMsg.setMsgContent(orderNo);
        int insert = localMsgMapper.insert(localMsg);
        log.info("保存本地消息到数据库{}",insert > 0 ? "成功":"失败");
    }

    /**
     * 保存订单减免信息
     * @param orderInfoVo 订单信息
     * @param orderId 订单Id
     */
    private void saveOrderDerateInfo(OrderInfoVo orderInfoVo, Long orderId) {
       orderInfoVo.getOrderDerateVoList().forEach(orderDerateVo -> {
           OrderDerate orderDerate = new OrderDerate();
           BeanUtils.copyProperties(orderDerateVo,orderDerate);
           orderDerate.setOrderId(orderId);
           int insert = orderDerateMapper.insert(orderDerate);
           log.info("保存订单减免信息到数据库{}",insert > 0 ? "成功":"失败");
       });
    }

    /**
     * 保存订单详情信息
     * @param orderInfoVo 订单信息
     * @param orderId 订单Id
     */
    private void saveOrderDetailInfo(OrderInfoVo orderInfoVo, Long orderId) {
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        orderDetailVoList.forEach(orderDetailVo -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            BeanUtils.copyProperties(orderDetailVo,orderDetail);
            int insert = orderDetailMapper.insert(orderDetail);
            log.info("保存订单详情信息到数据库{}",insert > 0 ? "成功":"失败");
        });
    }

    /**
     * 保存订单基本信息
     * @param orderNo 订单编号
     * @param orderInfoVo 订单信息
     * @param userId 用户Id
     */
    private OrderInfo saveOrderBasicInfo(String orderNo, OrderInfoVo orderInfoVo, Long userId) {
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(orderInfoVo,orderInfo);
        orderInfo.setOrderTitle(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
        orderInfo.setOrderStatus("0901");
        orderInfo.setOrderNo(orderNo);
        orderInfo.setUserId(userId);
        int insert = orderInfoMapper.insert(orderInfo);
        log.info("保存订单信息到数据库{}",insert > 0 ? "成功":"失败");
        return orderInfo;
    }

    /**
     * 处理付款项类型是专辑类型（1001）
     * @param tradeVo 购买类型及Id
     * @param userId 用户Id
     * @return 订单信息
     */
    private OrderInfoVo dealAlbumTypeItem(TradeVo tradeVo, Long userId) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        // 幂等性校验
        // 判断购买项是否已经买过（支付完毕）
        //获取专辑Id
        Long albumId = tradeVo.getItemId();
        String itemType = tradeVo.getItemType();
        Result<Boolean> userPaidAlbumResult = userInfoFeignClient.getUserPaidAlbum(albumId, userId);
        Boolean isPaidAlbum = userPaidAlbumResult.getData();
        Assert.notNull(isPaidAlbum, "远程调用获取用户是否购买专辑失败");
        if (isPaidAlbum) {
            log.error("该付款项目:{}已经购买过，请勿重复购买", albumId);
            throw new GuiguException(201, "该付款项目已经购买过，请勿重复购买");
        }
        // 判断购买项是否准备支付（支付中）
        //订单状态：0901-未支付 0902-已支付 0903-已取消
        int count = orderInfoMapper.checkAlbumAndVipTypeItemPadding(itemType, userId, albumId);
        if (count != 0) {
            log.error("该付款项专辑：{}，处于购买中，请勿继续购买该专辑", albumId);
            orderInfoVo.setExitItemIds(Lists.newArrayList(albumId));
            return orderInfoVo;
        }
        String tradeNo = RandomStringUtils.random(12, true, true);
        orderInfoVo.setTradeNo(tradeNo);
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(tradeVo.getItemType());
        //获取专辑信息价格
        Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlumInfo(albumId);
        AlbumInfo albumInfo = albumInfoResult.getData();
        Assert.notNull(albumInfo, "远程调用获取专辑信息失败");
        //原始金额
        BigDecimal originalPrice = albumInfo.getPrice();
        orderInfoVo.setOriginalAmount(originalPrice);
        //判断用户是否是Vip
        Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfo(userId);
        UserInfoVo userInfoVo = userInfoVoResult.getData();
        Assert.notNull(userInfoVo, "远程调用获取用户信息失败");
        Integer isVip = userInfoVo.getIsVip();
        //根据用户是否是Vip查询折扣力度
//        BigDecimal discount  = null;
//        if("1".equals(isVip.toString())){
//             discount  = albumInfo.getVipDiscount();
//        }else {
//            discount  = albumInfo.getDiscount();
//        }
        //折扣力度
        BigDecimal discount = "1".equals(isVip.toString()) ? albumInfo.getVipDiscount() : albumInfo.getDiscount();
        if ( discount.intValue() == -1) {
            // 没有折扣力度（不打折）
            discount = new BigDecimal("10.00");
        }
        // 计算优惠多少钱:原件：100 折扣力度：7 优惠：30=（100(原价)-[100（原价）*7（折扣力度）/10]）
        BigDecimal derateAmount = originalPrice.subtract(originalPrice.multiply(discount).divide(new BigDecimal("10.00")));
        orderInfoVo.setDerateAmount(derateAmount.setScale(2, RoundingMode.HALF_UP));
        //实付金额
        BigDecimal orderAmount = originalPrice.subtract(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        // 赋值订单的项数据
        ArrayList<OrderDetailVo> orderDetailVos = new ArrayList<>();
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        orderDetailVo.setItemId(albumId);
        orderDetailVo.setItemName(albumInfo.getAlbumTitle());
        orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
        orderDetailVo.setItemPrice(originalPrice);
        orderDetailVos.add(orderDetailVo);
        orderInfoVo.setOrderDetailVoList(orderDetailVos);
        // 3.7 赋值减免数据
        ArrayList<OrderDerateVo> orderDerateVos = new ArrayList<>();
        OrderDerateVo orderDerateVo = new OrderDerateVo();
        orderDerateVo.setDerateType("专辑折扣");
        orderDerateVo.setDerateAmount(derateAmount);
        orderDerateVo.setRemarks("订单减免类型专辑折扣减免");
        orderDerateVos.add(orderDerateVo);
        orderInfoVo.setOrderDerateVoList(orderDerateVos);
        //时间戳（未来在提交订单 判断订单失效行）
        orderInfoVo.setTimestamp(System.currentTimeMillis());
        return orderInfoVo;
    }

    /**
     * 处理付款项类型是声音类型（1002）
     *
     * @param tradeVo 购买类型及Id
     * @param userId  用户Id
     * @return 订单信息
     */
    private OrderInfoVo dealTrackTypeItem(TradeVo tradeVo, Long userId) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        Long trackId = tradeVo.getItemId();
        String itemType = tradeVo.getItemType();
        //购买声音集数
        Integer trackCount = tradeVo.getTrackCount();
        //获取声音对象信息
        Result<TrackInfo> trackInfoResult = albumInfoFeignClient.getTrackInfoById(trackId);
        TrackInfo trackInfo = trackInfoResult.getData();
        Assert.notNull(trackInfo, "远程调用获取声音信息失败");
        //获取专辑对象信息(以获取价格)
        Long albumId = trackInfo.getAlbumId();
        Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlumInfo(albumId);
        AlbumInfo albumInfo = albumInfoResult.getData();
        Assert.notNull(albumInfo, "远程调用获取专辑信息失败");
        // 幂等性校验
        // 综合方法（即能把买过的声音查询出来又能把买过的声音过滤掉 返回真正能买的声音）
        // 判断购买项是否已经买过（支付完毕）
        Result<List<TrackInfo>> canPayTrackList = albumInfoFeignClient.getPaidTrackAndFilterCanPayTrack(albumId, userId, trackCount, trackId);
        if (canPayTrackList.getCode() == 400) {
            List<TrackInfo> infoList = canPayTrackList.getData();
            List<Object> objects = new ArrayList<>(infoList);
            orderInfoVo.setExitItemIds(objects);
        }
        List<TrackInfo> canPayTrackListData = canPayTrackList.getData();
        Assert.notNull(canPayTrackListData, "远程调用获取声音信息失败");
        // 判断要买的声音中有没有存在正在支付中的
        // 将正在支付中的声音返回给前端（错误）
        // 将不在支付中的声音返给前端（真正要展示）
        List<Long> paddingTrackIds = orderInfoMapper.checkTrackTypeItemPadding(itemType, userId);
        List<Long> paddingTrackIdList = canPayTrackListData
                .stream()
                .map(TrackInfo::getId)
                .filter(paddingTrackIds::contains)
                .toList();
        // 要买的有声音中有存在支付中，收集起来返回给前端
        if (!CollectionUtils.isEmpty(paddingTrackIdList)) {
            List<Object> exitTrackList = new ArrayList<>();
            for (Long aLong : paddingTrackIdList) {
                exitTrackList.add(aLong);
                log.error("该付款项声音：{}，处于购买中，请勿继续购买该声音", aLong);
            }
            // 收集起来返给前端
            orderInfoVo.setExitItemIds(exitTrackList);
            return orderInfoVo;
        }
        orderInfoVo.setTradeNo(RandomStringUtils.random(12, true, true));
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(tradeVo.getItemType());
        BigDecimal trackPrice = albumInfo.getPrice();
        BigDecimal originAmount = trackCount == 0 ? trackPrice : trackPrice.multiply(new BigDecimal(trackCount));
        orderInfoVo.setOriginalAmount(originAmount);
        orderInfoVo.setDerateAmount(new BigDecimal("0.00")); // 优惠价格
        orderInfoVo.setOrderAmount(originAmount.setScale(2, RoundingMode.HALF_UP));// 实际金额

        ArrayList<OrderDetailVo> orderDetailVos = new ArrayList<>();
        for (TrackInfo trackListDatum : canPayTrackListData) {
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(trackListDatum.getId());
            orderDetailVo.setItemName(trackListDatum.getTrackTitle());
            orderDetailVo.setItemUrl(trackListDatum.getCoverUrl());
            orderDetailVo.setItemPrice(trackPrice.setScale(2, RoundingMode.HALF_UP));
            orderDetailVos.add(orderDetailVo);
        }

        orderInfoVo.setOrderDetailVoList(Lists.newArrayList(orderDetailVos));
        orderInfoVo.setOrderDerateVoList(Lists.newArrayList());// 声音不打折
        orderInfoVo.setTimestamp(System.currentTimeMillis());
        return orderInfoVo;
    }

    /**
     * 处理付款项类型是vip类型（1003）
     * @param tradeVo 购买类型及Id
     * @param userId 用户Id
     * @return 订单信息
     */
    private OrderInfoVo dealVipTypeItem(TradeVo tradeVo, Long userId) {
        // 获取套餐id
        Long itemId = tradeVo.getItemId();
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        String itemType = tradeVo.getItemType();
        // 校验付款项vip是否存在支付中
        int count = orderInfoMapper.checkAlbumAndVipTypeItemPadding(itemType, userId, itemId);
        if (count != 0) {
            log.error("该付款项vip套餐：{}，处于购买中，请勿继续购买", itemId);
            orderInfoVo.setExitItemIds(Lists.newArrayList(itemId));
            return orderInfoVo;
        }
        orderInfoVo.setTradeNo(RandomStringUtils.random(12, true, true));
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(itemType);

        //获取套餐信息
        Result<VipServiceConfig> vipServiceConfigResult = userInfoFeignClient.getAllVipConfig(itemId);
        VipServiceConfig vipServiceConfig = vipServiceConfigResult.getData();
        Assert.notNull(vipServiceConfig, "远程调用获取套餐信息失败");
        BigDecimal price = vipServiceConfig.getPrice();

        orderInfoVo.setOriginalAmount(price.setScale(2, RoundingMode.HALF_UP));
        BigDecimal discountPrice = vipServiceConfig.getDiscountPrice();
        orderInfoVo.setDerateAmount(price.subtract(discountPrice).setScale(2,RoundingMode.HALF_UP));
        orderInfoVo.setOrderAmount(discountPrice.setScale(2,RoundingMode.HALF_UP));
        //  给订单项属性赋值
        ArrayList<OrderDetailVo> orderDetailVos = new ArrayList<>();
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        orderDetailVo.setItemId(itemId);
        orderDetailVo.setItemName(vipServiceConfig.getName());
        orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
        orderDetailVo.setItemPrice(price.setScale(2,RoundingMode.HALF_UP));
        orderDetailVos.add(orderDetailVo);
        orderInfoVo.setOrderDetailVoList(Lists.newArrayList(orderDetailVos));
        // 给订单减免属性赋值
        ArrayList<OrderDerateVo> orderDerateVos = new ArrayList<>();
        OrderDerateVo orderDerateVo = new OrderDerateVo();
        orderDerateVo.setDerateType("VIP服务折");
        orderDerateVo.setDerateAmount(price.subtract(discountPrice).setScale(2,RoundingMode.HALF_UP));
        orderDerateVo.setRemarks("订单减免类型1406-VIP服务折扣");
        orderDerateVos.add(orderDerateVo);
        orderInfoVo.setOrderDerateVoList(Lists.newArrayList(orderDerateVos));

        orderInfoVo.setTimestamp(System.currentTimeMillis());
        return orderInfoVo;
    }
}
